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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <vector>
6 #include <openssl/evp.h>
7 #include <openssl/sha.h>
8
9 #include "base/logging.h"
10 #include "content/child/webcrypto/algorithm_implementation.h"
11 #include "content/child/webcrypto/crypto_data.h"
12 #include "content/child/webcrypto/openssl/util_openssl.h"
13 #include "content/child/webcrypto/status.h"
14 #include "content/child/webcrypto/webcrypto_util.h"
15 #include "crypto/openssl_util.h"
16 #include "crypto/scoped_openssl_types.h"
17
18 namespace content {
19
20 namespace webcrypto {
21
22 namespace {
23
24 // Implementation of blink::WebCryptoDigester, an internal Blink detail not
25 // part of WebCrypto, that allows chunks of data to be streamed in before
26 // computing a SHA-* digest (as opposed to ShaImplementation, which computes
27 // digests over complete messages)
28 class DigestorOpenSsl : public blink::WebCryptoDigestor {
29 public:
30 explicit DigestorOpenSsl(blink::WebCryptoAlgorithmId algorithm_id)
31 : initialized_(false),
32 digest_context_(EVP_MD_CTX_create()),
33 algorithm_id_(algorithm_id) {}
34
35 virtual bool consume(const unsigned char* data, unsigned int size) {
36 return ConsumeWithStatus(data, size).IsSuccess();
37 }
38
39 Status ConsumeWithStatus(const unsigned char* data, unsigned int size) {
40 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
41 Status error = Init();
42 if (!error.IsSuccess())
43 return error;
44
45 if (!EVP_DigestUpdate(digest_context_.get(), data, size))
46 return Status::OperationError();
47
48 return Status::Success();
49 }
50
51 virtual bool finish(unsigned char*& result_data,
52 unsigned int& result_data_size) {
53 Status error = FinishInternal(result_, &result_data_size);
54 if (!error.IsSuccess())
55 return false;
56 result_data = result_;
57 return true;
58 }
59
60 Status FinishWithVectorAndStatus(std::vector<uint8>* result) {
61 const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get());
62 result->resize(hash_expected_size);
63 unsigned char* const hash_buffer = Uint8VectorStart(result);
64 unsigned int hash_buffer_size; // ignored
65 return FinishInternal(hash_buffer, &hash_buffer_size);
66 }
67
68 private:
69 Status Init() {
70 if (initialized_)
71 return Status::Success();
72
73 const EVP_MD* digest_algorithm = GetDigest(algorithm_id_);
74 if (!digest_algorithm)
75 return Status::ErrorUnexpected();
76
77 if (!digest_context_.get())
78 return Status::OperationError();
79
80 if (!EVP_DigestInit_ex(digest_context_.get(), digest_algorithm, NULL))
81 return Status::OperationError();
82
83 initialized_ = true;
84 return Status::Success();
85 }
86
87 Status FinishInternal(unsigned char* result, unsigned int* result_size) {
88 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
89 Status error = Init();
90 if (!error.IsSuccess())
91 return error;
92
93 const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get());
94 if (hash_expected_size <= 0)
95 return Status::ErrorUnexpected();
96 DCHECK_LE(hash_expected_size, EVP_MAX_MD_SIZE);
97
98 if (!EVP_DigestFinal_ex(digest_context_.get(), result, result_size) ||
99 static_cast<int>(*result_size) != hash_expected_size)
100 return Status::OperationError();
101
102 return Status::Success();
103 }
104
105 bool initialized_;
106 crypto::ScopedEVP_MD_CTX digest_context_;
107 blink::WebCryptoAlgorithmId algorithm_id_;
108 unsigned char result_[EVP_MAX_MD_SIZE];
109 };
110
111 class ShaImplementation : public AlgorithmImplementation {
112 public:
113 virtual Status Digest(const blink::WebCryptoAlgorithm& algorithm,
114 const CryptoData& data,
115 std::vector<uint8>* buffer) const OVERRIDE {
116 DigestorOpenSsl digestor(algorithm.id());
117 Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
118 // http://crbug.com/366427: the spec does not define any other failures for
119 // digest, so none of the subsequent errors are spec compliant.
120 if (!error.IsSuccess())
121 return error;
122 return digestor.FinishWithVectorAndStatus(buffer);
123 }
124 };
125
126 } // namespace
127
128 AlgorithmImplementation* CreatePlatformShaImplementation() {
129 return new ShaImplementation();
130 }
131
132 scoped_ptr<blink::WebCryptoDigestor> CreatePlatformDigestor(
133 blink::WebCryptoAlgorithmId algorithm) {
134 return scoped_ptr<blink::WebCryptoDigestor>(new DigestorOpenSsl(algorithm));
135 }
136
137 } // namespace webcrypto
138
139 } // namespace content
OLDNEW
« 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