summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-19 15:11:33 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-19 15:11:33 +0000
commit7c3090a02e256e1fc42d37123195caa134cb487b (patch)
tree73f7463b09c7e980206a3a8f1f0a963f97e4d529
parent7cd51e7bf5a86cd362c35119a138bc4969579c74 (diff)
downloadchromium_src-7c3090a02e256e1fc42d37123195caa134cb487b.zip
chromium_src-7c3090a02e256e1fc42d37123195caa134cb487b.tar.gz
chromium_src-7c3090a02e256e1fc42d37123195caa134cb487b.tar.bz2
crypto: add DecodeSignature and use SHA-256 with ECDSA.
This changes ECSignatureCreator to use the hash function that SPDY expects (SHA-256). There are no other users of ECSignatureCreator in the tree so I'm going to defer making these choices parameters until there's a benefit to be had. It also adds DecodeSignature to convert from ASN.1 signatures to the `raw' form that SPDY needs. BUG=none Review URL: https://chromiumcodereview.appspot.com/10910226 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157551 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--crypto/ec_signature_creator.h11
-rw-r--r--crypto/ec_signature_creator_impl.h4
-rw-r--r--crypto/ec_signature_creator_nss.cc26
-rw-r--r--crypto/ec_signature_creator_openssl.cc6
-rw-r--r--crypto/ec_signature_creator_unittest.cc14
-rw-r--r--net/spdy/spdy_credential_builder.cc10
-rw-r--r--net/spdy/spdy_test_util_spdy3.cc6
7 files changed, 64 insertions, 13 deletions
diff --git a/crypto/ec_signature_creator.h b/crypto/ec_signature_creator.h
index b557daa..16e64f5 100644
--- a/crypto/ec_signature_creator.h
+++ b/crypto/ec_signature_creator.h
@@ -5,6 +5,7 @@
#ifndef CRYPTO_EC_SIGNATURE_CREATOR_H_
#define CRYPTO_EC_SIGNATURE_CREATOR_H_
+#include <string>
#include <vector>
#include "base/basictypes.h"
@@ -31,7 +32,7 @@ class CRYPTO_EXPORT ECSignatureCreator {
// Create an instance. The caller must ensure that the provided PrivateKey
// instance outlives the created ECSignatureCreator.
- // TODO(rch): This is currently hard coded to use SHA1. Ideally, we should
+ // TODO(rch): This is currently hard coded to use SHA256. Ideally, we should
// pass in the hash algorithm identifier.
static ECSignatureCreator* Create(ECPrivateKey* key);
@@ -50,6 +51,14 @@ class CRYPTO_EXPORT ECSignatureCreator {
virtual bool Sign(const uint8* data,
int data_len,
std::vector<uint8>* signature) = 0;
+
+ // DecodeSignature converts from a DER encoded ECDSA-Sig-Value (as produced
+ // by Sign) to a `raw' ECDSA signature which consists of a pair of
+ // big-endian, zero-padded, 256-bit integers, r and s. On success it returns
+ // true and puts the raw signature into |out_raw_sig|.
+ // (Only P-256 signatures are supported.)
+ virtual bool DecodeSignature(const std::vector<uint8>& signature,
+ std::vector<uint8>* out_raw_sig) = 0;
};
} // namespace crypto
diff --git a/crypto/ec_signature_creator_impl.h b/crypto/ec_signature_creator_impl.h
index f8baf86..8ef67cd 100644
--- a/crypto/ec_signature_creator_impl.h
+++ b/crypto/ec_signature_creator_impl.h
@@ -19,8 +19,12 @@ class ECSignatureCreatorImpl : public ECSignatureCreator {
int data_len,
std::vector<uint8>* signature) OVERRIDE;
+ virtual bool DecodeSignature(const std::vector<uint8>& der_sig,
+ std::vector<uint8>* out_raw_sig) OVERRIDE;
+
private:
ECPrivateKey* key_;
+ size_t signature_len_;
DISALLOW_COPY_AND_ASSIGN(ECSignatureCreatorImpl);
};
diff --git a/crypto/ec_signature_creator_nss.cc b/crypto/ec_signature_creator_nss.cc
index a85b1e9..3e3626f 100644
--- a/crypto/ec_signature_creator_nss.cc
+++ b/crypto/ec_signature_creator_nss.cc
@@ -24,7 +24,8 @@ namespace {
SECStatus SignData(SECItem* result,
SECItem* input,
SECKEYPrivateKey* key,
- HASH_HashType hash_type) {
+ HASH_HashType hash_type,
+ size_t* out_signature_len) {
if (key->keyType != ecKey) {
DLOG(FATAL) << "Should be using an EC key.";
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -49,6 +50,8 @@ SECStatus SignData(SECItem* result,
if (rv != SECSuccess)
return rv;
+ *out_signature_len = sig.len;
+
// DER encode the signature.
return DSAU_EncodeDerSigWithLen(result, &sig, sig.len);
}
@@ -56,7 +59,8 @@ SECStatus SignData(SECItem* result,
} // namespace
ECSignatureCreatorImpl::ECSignatureCreatorImpl(ECPrivateKey* key)
- : key_(key) {
+ : key_(key),
+ signature_len_(0) {
EnsureNSSInit();
}
@@ -79,7 +83,7 @@ bool ECSignatureCreatorImpl::Sign(const uint8* data,
// Sign the secret data and save it to |result|.
SECStatus rv =
- SignData(&result, &secret, key_->key(), HASH_AlgSHA1);
+ SignData(&result, &secret, key_->key(), HASH_AlgSHA256, &signature_len_);
if (rv != SECSuccess) {
DLOG(ERROR) << "DerSignData: " << PORT_GetError();
return false;
@@ -91,4 +95,20 @@ bool ECSignatureCreatorImpl::Sign(const uint8* data,
return true;
}
+bool ECSignatureCreatorImpl::DecodeSignature(
+ const std::vector<uint8>& der_sig,
+ std::vector<uint8>* out_raw_sig) {
+ SECItem der_sig_item;
+ der_sig_item.type = siBuffer;
+ der_sig_item.len = der_sig.size();
+ der_sig_item.data = const_cast<uint8*>(&der_sig[0]);
+
+ SECItem* raw_sig = DSAU_DecodeDerSigToLen(&der_sig_item, signature_len_);
+ if (!raw_sig)
+ return false;
+ out_raw_sig->assign(raw_sig->data, raw_sig->data + raw_sig->len);
+ SECITEM_FreeItem(raw_sig, PR_TRUE /* free SECItem structure itself. */);
+ return true;
+}
+
} // namespace crypto
diff --git a/crypto/ec_signature_creator_openssl.cc b/crypto/ec_signature_creator_openssl.cc
index ae443c4..8854f5e 100644
--- a/crypto/ec_signature_creator_openssl.cc
+++ b/crypto/ec_signature_creator_openssl.cc
@@ -22,4 +22,10 @@ bool ECSignatureCreatorImpl::Sign(const uint8* data,
return false;
}
+bool ECSignatureCreatorImpl::DecodeSignature(const std::vector<uint8>& der_sig,
+ std::vector<uint8>* out_raw_sig) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
} // namespace crypto
diff --git a/crypto/ec_signature_creator_unittest.cc b/crypto/ec_signature_creator_unittest.cc
index 407b278..df73bec 100644
--- a/crypto/ec_signature_creator_unittest.cc
+++ b/crypto/ec_signature_creator_unittest.cc
@@ -53,17 +53,17 @@ TEST(ECSignatureCreatorTest, BasicTest) {
std::vector<uint8> public_key_info;
ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));
- // This is the algorithm ID for SHA-1 with EC encryption.
- const uint8 kECDSAWithSHA1AlgorithmID[] = {
- 0x30, 0x0b,
- 0x06, 0x07,
- 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01,
+ // This is the algorithm ID for SHA-256 with EC encryption.
+ const uint8 kECDSAWithSHA256AlgorithmID[] = {
+ 0x30, 0x0c,
+ 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
0x05, 0x00
};
crypto::SignatureVerifier verifier;
ASSERT_TRUE(verifier.VerifyInit(
- kECDSAWithSHA1AlgorithmID, sizeof(kECDSAWithSHA1AlgorithmID),
- &signature.front(), signature.size(),
+ kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
+ &signature[0], signature.size(),
&public_key_info.front(), public_key_info.size()));
verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()),
diff --git a/net/spdy/spdy_credential_builder.cc b/net/spdy/spdy_credential_builder.cc
index accd33d..8ddda97 100644
--- a/net/spdy/spdy_credential_builder.cc
+++ b/net/spdy/spdy_credential_builder.cc
@@ -55,7 +55,7 @@ int SpdyCredentialBuilder::Build(const std::string& tls_unique,
public_key = public_key.substr(2, public_key.length());
// Convert the strings into a vector<unit8>
- std::vector<uint8> proof_vector;
+ std::vector<uint8> der_signature;
scoped_ptr<crypto::ECPrivateKey> private_key(
crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
ServerBoundCertService::kEPKIPassword,
@@ -63,7 +63,13 @@ int SpdyCredentialBuilder::Build(const std::string& tls_unique,
scoped_ptr<crypto::ECSignatureCreator> creator(
crypto::ECSignatureCreator::Create(private_key.get()));
creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()),
- secret.length(), &proof_vector);
+ secret.length(), &der_signature);
+
+ std::vector<uint8> proof_vector;
+ if (!creator->DecodeSignature(der_signature, &proof_vector)) {
+ NOTREACHED();
+ return ERR_UNEXPECTED;
+ }
credential->slot = slot;
credential->certs.push_back(public_key.as_string());
diff --git a/net/spdy/spdy_test_util_spdy3.cc b/net/spdy/spdy_test_util_spdy3.cc
index cffd9eb..6598a49 100644
--- a/net/spdy/spdy_test_util_spdy3.cc
+++ b/net/spdy/spdy_test_util_spdy3.cc
@@ -63,6 +63,12 @@ class MockECSignatureCreator : public crypto::ECSignatureCreator {
return true;
}
+ virtual bool DecodeSignature(const std::vector<uint8>& signature,
+ std::vector<uint8>* out_raw_sig) {
+ *out_raw_sig = signature;
+ return true;
+ }
+
private:
crypto::ECPrivateKey* key_;