Skip to content

Commit 84a7880

Browse files
jasnellnodejs-github-bot
authored andcommitted
src: minor cleanup and simplification of crypto::Hash
Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #35651 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 1103b15 commit 84a7880

File tree

2 files changed

+25
-34
lines changed

2 files changed

+25
-34
lines changed

src/crypto/crypto_hash.cc

+22-28
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,13 @@ using v8::Uint32;
2424
using v8::Value;
2525

2626
namespace crypto {
27-
Hash::Hash(Environment* env, Local<Object> wrap)
28-
: BaseObject(env, wrap),
29-
mdctx_(nullptr),
30-
has_md_(false),
31-
md_value_(nullptr) {
27+
Hash::Hash(Environment* env, Local<Object> wrap) : BaseObject(env, wrap) {
3228
MakeWeak();
3329
}
3430

3531
void Hash::MemoryInfo(MemoryTracker* tracker) const {
3632
tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0);
37-
tracker->TrackFieldWithSize("md", md_len_);
33+
tracker->TrackFieldWithSize("md", digest_ ? md_len_ : 0);
3834
}
3935

4036
void Hash::GetHashes(const FunctionCallbackInfo<Value>& args) {
@@ -63,11 +59,6 @@ void Hash::Initialize(Environment* env, Local<Object> target) {
6359
HashJob::Initialize(env, target);
6460
}
6561

66-
Hash::~Hash() {
67-
if (md_value_ != nullptr)
68-
OPENSSL_clear_free(md_value_, md_len_);
69-
}
70-
7162
void Hash::New(const FunctionCallbackInfo<Value>& args) {
7263
Environment* env = Environment::GetCurrent(args);
7364

@@ -150,47 +141,50 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
150141
encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
151142
}
152143

144+
unsigned int len = hash->md_len_;
145+
153146
// TODO(tniessen): SHA3_squeeze does not work for zero-length outputs on all
154147
// platforms and will cause a segmentation fault if called. This workaround
155148
// causes hash.digest() to correctly return an empty buffer / string.
156149
// See https://github.com/openssl/openssl/issues/9431.
157-
if (!hash->has_md_ && hash->md_len_ == 0) {
158-
hash->has_md_ = true;
159-
}
160150

161-
if (!hash->has_md_) {
151+
if (!hash->digest_ && len > 0) {
162152
// Some hash algorithms such as SHA3 do not support calling
163153
// EVP_DigestFinal_ex more than once, however, Hash._flush
164154
// and Hash.digest can both be used to retrieve the digest,
165155
// so we need to cache it.
166156
// See https://github.com/nodejs/node/issues/28245.
167157

168-
hash->md_value_ = MallocOpenSSL<unsigned char>(hash->md_len_);
158+
char* md_value = MallocOpenSSL<char>(len);
159+
ByteSource digest = ByteSource::Allocated(md_value, len);
169160

170161
size_t default_len = EVP_MD_CTX_size(hash->mdctx_.get());
171162
int ret;
172-
if (hash->md_len_ == default_len) {
173-
ret = EVP_DigestFinal_ex(hash->mdctx_.get(), hash->md_value_,
174-
&hash->md_len_);
163+
if (len == default_len) {
164+
ret = EVP_DigestFinal_ex(
165+
hash->mdctx_.get(),
166+
reinterpret_cast<unsigned char*>(md_value),
167+
&len);
168+
// The output length should always equal hash->md_len_
169+
CHECK_EQ(len, hash->md_len_);
175170
} else {
176-
ret = EVP_DigestFinalXOF(hash->mdctx_.get(), hash->md_value_,
177-
hash->md_len_);
171+
ret = EVP_DigestFinalXOF(
172+
hash->mdctx_.get(),
173+
reinterpret_cast<unsigned char*>(md_value),
174+
len);
178175
}
179176

180-
if (ret != 1) {
181-
OPENSSL_free(hash->md_value_);
182-
hash->md_value_ = nullptr;
177+
if (ret != 1)
183178
return ThrowCryptoError(env, ERR_get_error());
184-
}
185179

186-
hash->has_md_ = true;
180+
hash->digest_ = std::move(digest);
187181
}
188182

189183
Local<Value> error;
190184
MaybeLocal<Value> rc =
191185
StringBytes::Encode(env->isolate(),
192-
reinterpret_cast<const char*>(hash->md_value_),
193-
hash->md_len_,
186+
hash->digest_.get(),
187+
len,
194188
encoding,
195189
&error);
196190
if (rc.IsEmpty()) {

src/crypto/crypto_hash.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ namespace node {
1515
namespace crypto {
1616
class Hash final : public BaseObject {
1717
public:
18-
~Hash() override;
19-
2018
static void Initialize(Environment* env, v8::Local<v8::Object> target);
2119

2220
void MemoryInfo(MemoryTracker* tracker) const override;
@@ -36,10 +34,9 @@ class Hash final : public BaseObject {
3634
Hash(Environment* env, v8::Local<v8::Object> wrap);
3735

3836
private:
39-
EVPMDPointer mdctx_;
40-
bool has_md_;
41-
unsigned int md_len_;
42-
unsigned char* md_value_;
37+
EVPMDPointer mdctx_ {};
38+
unsigned int md_len_ = 0;
39+
ByteSource digest_;
4340
};
4441

4542
struct HashConfig final : public MemoryRetainer {

0 commit comments

Comments
 (0)