Index: content/child/webcrypto/platform_crypto_nss.cc |
diff --git a/content/child/webcrypto/platform_crypto_nss.cc b/content/child/webcrypto/platform_crypto_nss.cc |
index 242db07a23a1c52fb866cd4840eee4510fae7294..54e1fd6707545e7ca1c8c6e9374e6e8d2c115861 100644 |
--- a/content/child/webcrypto/platform_crypto_nss.cc |
+++ b/content/child/webcrypto/platform_crypto_nss.cc |
@@ -14,6 +14,7 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
#include "content/child/webcrypto/crypto_data.h" |
#include "content/child/webcrypto/status.h" |
#include "content/child/webcrypto/webcrypto_util.h" |
@@ -654,6 +655,94 @@ struct FreeRsaPrivateKey { |
} // namespace |
+class DigestorNSS : public blink::WebCryptoDigestor { |
+ public: |
+ explicit DigestorNSS(blink::WebCryptoAlgorithmId algorithm_id) |
+ : hash_context_(NULL), algorithm_id_(algorithm_id) {} |
+ |
+ virtual ~DigestorNSS() OVERRIDE { |
eroman
2014/03/26 01:43:54
no need for override here, suggest removing (in pr
jww
2014/03/26 18:49:40
Done.
|
+ if (!hash_context_) |
+ return; |
+ |
+ HASH_Destroy(hash_context_); |
+ hash_context_ = NULL; |
+ } |
+ |
+ virtual bool consume(const unsigned char* data, unsigned int size) { |
+ return ConsumeWithStatus(data, size).IsSuccess(); |
+ } |
+ |
+ Status ConsumeWithStatus(const unsigned char* data, unsigned int size) { |
+ // Initialize everything if the object hasn't been initialized yet. |
+ if (!hash_context_) { |
+ Status error = Init(); |
+ if (!error.IsSuccess()) |
+ return error; |
+ } |
+ |
+ HASH_Update(hash_context_, data, size); |
+ |
+ return Status::Success(); |
+ } |
+ |
+ virtual bool finish(unsigned char*& result_data, |
+ unsigned int& result_data_size) { |
+ Status error = FinishInternal(result_, &result_data_size); |
+ if (!error.IsSuccess()) |
+ return false; |
+ result_data = result_; |
+ return true; |
+ } |
+ |
+ Status FinishWithWebArrayAndStatus(blink::WebArrayBuffer* result) { |
+ if (!hash_context_) |
+ return Status::ErrorUnexpected(); |
+ |
+ unsigned int result_length = HASH_ResultLenContext(hash_context_); |
+ *result = blink::WebArrayBuffer::create(result_length, 1); |
+ unsigned char* digest = reinterpret_cast<unsigned char*>(result->data()); |
+ unsigned int digest_size; // ignored |
+ return FinishInternal(digest, &digest_size); |
+ } |
+ |
+ private: |
+ HASHContext* hash_context_; |
eroman
2014/03/26 01:43:54
[style] members go after functions. Move all the m
jww
2014/03/26 18:49:40
Done.
|
+ blink::WebCryptoAlgorithmId algorithm_id_; |
+ unsigned char result_[HASH_LENGTH_MAX]; |
+ |
+ Status Init() { |
+ HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_); |
+ |
+ if (hash_type == HASH_AlgNULL) |
+ return Status::ErrorUnsupported(); |
+ |
+ hash_context_ = HASH_Create(hash_type); |
+ if (!hash_context_) |
+ return Status::Error(); |
+ |
+ HASH_Begin(hash_context_); |
+ |
+ return Status::Success(); |
+ } |
+ |
+ Status FinishInternal(unsigned char* result, unsigned int* result_size) { |
+ if (!hash_context_) { |
+ Status error = Init(); |
+ if (!error.IsSuccess()) |
+ return error; |
+ } |
+ |
+ unsigned int hash_result_length = HASH_ResultLenContext(hash_context_); |
+ DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); |
+ |
+ HASH_End(hash_context_, result, result_size, hash_result_length); |
+ |
+ if (*result_size != hash_result_length) |
+ return Status::ErrorUnexpected(); |
+ return Status::Success(); |
+ } |
+}; |
+ |
Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
const CryptoData& key_data, |
bool extractable, |
@@ -1177,33 +1266,16 @@ void Init() { crypto::EnsureNSSInit(); } |
Status DigestSha(blink::WebCryptoAlgorithmId algorithm, |
const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); |
- if (hash_type == HASH_AlgNULL) |
- return Status::ErrorUnsupported(); |
- |
- HASHContext* context = HASH_Create(hash_type); |
- if (!context) |
- return Status::Error(); |
- |
- HASH_Begin(context); |
- |
- HASH_Update(context, data.bytes(), data.byte_length()); |
- |
- unsigned int hash_result_length = HASH_ResultLenContext(context); |
- DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); |
- |
- *buffer = blink::WebArrayBuffer::create(hash_result_length, 1); |
- |
- unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); |
- |
- unsigned int result_length = 0; |
- HASH_End(context, digest, &result_length, hash_result_length); |
- |
- HASH_Destroy(context); |
+ DigestorNSS digestor(algorithm); |
+ Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length()); |
+ if (!error.IsSuccess()) |
+ return error; |
+ return digestor.FinishWithWebArrayAndStatus(buffer); |
+} |
- if (result_length != hash_result_length) |
- return Status::ErrorUnexpected(); |
- return Status::Success(); |
+scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( |
+ blink::WebCryptoAlgorithmId algorithm_id) { |
+ return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm_id)); |
} |
Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |