Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Unified Diff: content/child/webcrypto/openssl/sha_openssl.cc

Issue 379383002: Refactor WebCrypto code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase onto master (no longer has BoringSSL) Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/child/webcrypto/openssl/key_openssl.cc ('k') | content/child/webcrypto/openssl/sym_key_openssl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/openssl/sha_openssl.cc
diff --git a/content/child/webcrypto/openssl/sha_openssl.cc b/content/child/webcrypto/openssl/sha_openssl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f9382b558f8088a6758548d57b1f0a372f93163f
--- /dev/null
+++ b/content/child/webcrypto/openssl/sha_openssl.cc
@@ -0,0 +1,139 @@
+// 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.
+
+#include <vector>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#include "base/logging.h"
+#include "content/child/webcrypto/algorithm_implementation.h"
+#include "content/child/webcrypto/crypto_data.h"
+#include "content/child/webcrypto/openssl/util_openssl.h"
+#include "content/child/webcrypto/status.h"
+#include "content/child/webcrypto/webcrypto_util.h"
+#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
+
+namespace content {
+
+namespace webcrypto {
+
+namespace {
+
+// Implementation of blink::WebCryptoDigester, an internal Blink detail not
+// part of WebCrypto, that allows chunks of data to be streamed in before
+// computing a SHA-* digest (as opposed to ShaImplementation, which computes
+// digests over complete messages)
+class DigestorOpenSsl : public blink::WebCryptoDigestor {
+ public:
+ explicit DigestorOpenSsl(blink::WebCryptoAlgorithmId algorithm_id)
+ : initialized_(false),
+ digest_context_(EVP_MD_CTX_create()),
+ algorithm_id_(algorithm_id) {}
+
+ virtual bool consume(const unsigned char* data, unsigned int size) {
+ return ConsumeWithStatus(data, size).IsSuccess();
+ }
+
+ Status ConsumeWithStatus(const unsigned char* data, unsigned int size) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+ Status error = Init();
+ if (!error.IsSuccess())
+ return error;
+
+ if (!EVP_DigestUpdate(digest_context_.get(), data, size))
+ return Status::OperationError();
+
+ 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 FinishWithVectorAndStatus(std::vector<uint8>* result) {
+ const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get());
+ result->resize(hash_expected_size);
+ unsigned char* const hash_buffer = Uint8VectorStart(result);
+ unsigned int hash_buffer_size; // ignored
+ return FinishInternal(hash_buffer, &hash_buffer_size);
+ }
+
+ private:
+ Status Init() {
+ if (initialized_)
+ return Status::Success();
+
+ const EVP_MD* digest_algorithm = GetDigest(algorithm_id_);
+ if (!digest_algorithm)
+ return Status::ErrorUnexpected();
+
+ if (!digest_context_.get())
+ return Status::OperationError();
+
+ if (!EVP_DigestInit_ex(digest_context_.get(), digest_algorithm, NULL))
+ return Status::OperationError();
+
+ initialized_ = true;
+ return Status::Success();
+ }
+
+ Status FinishInternal(unsigned char* result, unsigned int* result_size) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+ Status error = Init();
+ if (!error.IsSuccess())
+ return error;
+
+ const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get());
+ if (hash_expected_size <= 0)
+ return Status::ErrorUnexpected();
+ DCHECK_LE(hash_expected_size, EVP_MAX_MD_SIZE);
+
+ if (!EVP_DigestFinal_ex(digest_context_.get(), result, result_size) ||
+ static_cast<int>(*result_size) != hash_expected_size)
+ return Status::OperationError();
+
+ return Status::Success();
+ }
+
+ bool initialized_;
+ crypto::ScopedEVP_MD_CTX digest_context_;
+ blink::WebCryptoAlgorithmId algorithm_id_;
+ unsigned char result_[EVP_MAX_MD_SIZE];
+};
+
+class ShaImplementation : public AlgorithmImplementation {
+ public:
+ virtual Status Digest(const blink::WebCryptoAlgorithm& algorithm,
+ const CryptoData& data,
+ std::vector<uint8>* buffer) const OVERRIDE {
+ DigestorOpenSsl digestor(algorithm.id());
+ Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
+ // http://crbug.com/366427: the spec does not define any other failures for
+ // digest, so none of the subsequent errors are spec compliant.
+ if (!error.IsSuccess())
+ return error;
+ return digestor.FinishWithVectorAndStatus(buffer);
+ }
+};
+
+} // namespace
+
+AlgorithmImplementation* CreatePlatformShaImplementation() {
+ return new ShaImplementation();
+}
+
+scoped_ptr<blink::WebCryptoDigestor> CreatePlatformDigestor(
+ blink::WebCryptoAlgorithmId algorithm) {
+ return scoped_ptr<blink::WebCryptoDigestor>(new DigestorOpenSsl(algorithm));
+}
+
+} // namespace webcrypto
+
+} // namespace content
« no previous file with comments | « content/child/webcrypto/openssl/key_openssl.cc ('k') | content/child/webcrypto/openssl/sym_key_openssl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698