Skip to content

Commit

Permalink
fixup! crypto: implement crypto.digest()
Browse files Browse the repository at this point in the history
  • Loading branch information
joyeecheung committed Jan 6, 2024
1 parent 1131ee0 commit 444fec1
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 31 deletions.
2 changes: 1 addition & 1 deletion benchmark/crypto/node-digest.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function main({ length, type, method, n }) {
}

const hash = digest ?
(method, input) => digest(method, input, { outputEncoding: 'hex' }) :
(method, input) => digest(method, input, 'hex') :
(method, input) => createHash(method).update(input).digest('hex');
const array = [];
for (let i = 0; i < n; i++) {
Expand Down
18 changes: 6 additions & 12 deletions lib/internal/crypto/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,18 @@ async function asyncDigest(algorithm, data) {
throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
}

function digest(algorithm, input, options) {
function digest(algorithm, input, outputEncoding = 'hex') {
validateString(algorithm, 'algorithm');
if (typeof input !== 'string') {
validateBuffer(input, 'input');
}
let inputEncoding = 'utf8';
let outputEncoding = 'buffer';
if (typeof options === 'object') {
if (typeof options.inputEncoding === 'string') {
inputEncoding = normalizeEncoding(options.inputEncoding) || inputEncoding;
}
if (typeof options.outputEncoding === 'string') {
outputEncoding = normalizeEncoding(options.outputEncoding) || outputEncoding;
}
// Fast case: if it's 'hex', we don't need to validate it further.
if (outputEncoding !== 'hex') {
validateString(outputEncoding);
outputEncoding = normalizeEncoding(outputEncoding) || outputEncoding;
}
return oneShotDigest(algorithm, getCachedHashId(algorithm), getHashCache(),
input, inputEncoding, encodingsMap[inputEncoding],
outputEncoding, encodingsMap[outputEncoding]);
input, outputEncoding, encodingsMap[outputEncoding]);
}

module.exports = {
Expand Down
26 changes: 8 additions & 18 deletions src/crypto/crypto_hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,20 +204,17 @@ const EVP_MD* GetDigestImplementation(Environment* env,
}

// crypto.digest(algorithm, algorithmId, algorithmCache,
// input, inputEncoding, inputEncodingId,
// outputEncoding, outputEncodingId)
// input, outputEncoding, outputEncodingId)
void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Isolate* isolate = env->isolate();
CHECK_EQ(args.Length(), 8);
CHECK_EQ(args.Length(), 6);
CHECK(args[0]->IsString()); // algorithm
CHECK(args[1]->IsInt32()); // algorithmId
CHECK(args[2]->IsObject()); // algorithmCache
CHECK(args[3]->IsString() || args[3]->IsArrayBufferView()); // input
CHECK(args[4]->IsString()); // inputEncoding
CHECK(args[5]->IsUint32() || args[5]->IsUndefined()); // inputEncodingId
CHECK(args[6]->IsString()); // outputEncoding
CHECK(args[7]->IsUint32() || args[7]->IsUndefined()); // outputEncodingId
CHECK(args[4]->IsString()); // outputEncoding
CHECK(args[5]->IsUint32() || args[5]->IsUndefined()); // outputEncodingId

const EVP_MD* md = GetDigestImplementation(env, args[0], args[1], args[2]);
if (md == nullptr) {
Expand All @@ -227,8 +224,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
return ThrowCryptoError(env, ERR_get_error(), message.c_str());
}

enum encoding input_enc = ParseEncoding(isolate, args[4], args[5], UTF8);
enum encoding output_enc = ParseEncoding(isolate, args[6], args[7], BUFFER);
enum encoding output_enc = ParseEncoding(isolate, args[4], args[5], HEX);

int md_len = EVP_MD_size(md);
unsigned int result_size;
Expand All @@ -241,15 +237,9 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
// in the future.
// https://github.com/openssl/openssl/issues/19612
if (args[3]->IsString()) {
StringBytes::InlineDecoder decoder;
// Input is a string so it must be decodable.
decoder.Decode(env, args[3].As<String>(), input_enc).Check();
if (UNLIKELY(decoder.size() > INT_MAX)) {
return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
}

success = EVP_Digest(decoder.out(),
decoder.size(),
Utf8Value utf8(isolate, args[3]);
success = EVP_Digest(utf8.out(),
utf8.length(),
output.data<unsigned char>(),
&result_size,
md,
Expand Down

0 comments on commit 444fec1

Please sign in to comment.