Skip to content

Commit 14a6c4e

Browse files
committed
crypto: add crypto.getHashes()
1 parent f53441a commit 14a6c4e

4 files changed

Lines changed: 51 additions & 0 deletions

File tree

doc/api/crypto.markdown

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ Example:
2121
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]
2222

2323

24+
## crypto.getHashes()
25+
26+
Returns an array with the names of the supported hash algorithms.
27+
28+
Example:
29+
30+
var hashes = crypto.getHashes();
31+
console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
32+
33+
2434
## crypto.createCredentials(details)
2535

2636
Creates a credentials object, with the optional details being a dictionary with keys:

lib/crypto.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ try {
3535
var randomBytes = binding.randomBytes;
3636
var pseudoRandomBytes = binding.pseudoRandomBytes;
3737
var getCiphers = binding.getCiphers;
38+
var getHashes = binding.getHashes;
3839
var crypto = true;
3940
} catch (e) {
4041

@@ -196,3 +197,18 @@ exports.rng = randomBytes;
196197
exports.prng = pseudoRandomBytes;
197198

198199
exports.getCiphers = getCiphers;
200+
201+
exports.getHashes = function() {
202+
var names = getHashes.call(null, arguments);
203+
204+
// Drop all-caps names in favor of their lowercase aliases,
205+
// for example, 'sha1' instead of 'SHA1'.
206+
var ctx = {};
207+
names = names.forEach(function(name) {
208+
if (/^[0-9A-Z\-]+$/.test(name)) name = name.toLowerCase();
209+
ctx[name] = true;
210+
});
211+
names = Object.getOwnPropertyNames(ctx);
212+
213+
return names;
214+
};

src/node_crypto.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4646,6 +4646,23 @@ Handle<Value> GetCiphers(const Arguments& args) {
46464646
}
46474647

46484648

4649+
static void add_hash_to_array(const EVP_MD* md,
4650+
const char* from,
4651+
const char* to,
4652+
void* arg) {
4653+
Local<Array>& arr = *static_cast<Local<Array>*>(arg);
4654+
arr->Set(arr->Length(), String::New(from));
4655+
}
4656+
4657+
4658+
Handle<Value> GetHashes(const Arguments& args) {
4659+
HandleScope scope;
4660+
Local<Array> arr = Array::New();
4661+
EVP_MD_do_all_sorted(add_hash_to_array, &arr);
4662+
return scope.Close(arr);
4663+
}
4664+
4665+
46494666
void InitCrypto(Handle<Object> target) {
46504667
HandleScope scope;
46514668

@@ -4686,6 +4703,7 @@ void InitCrypto(Handle<Object> target) {
46864703
NODE_SET_METHOD(target, "randomBytes", RandomBytes<RAND_bytes>);
46874704
NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<RAND_pseudo_bytes>);
46884705
NODE_SET_METHOD(target, "getCiphers", GetCiphers);
4706+
NODE_SET_METHOD(target, "getHashes", GetHashes);
46894707

46904708
subject_symbol = NODE_PSYMBOL("subject");
46914709
issuer_symbol = NODE_PSYMBOL("issuer");

test/simple/test-crypto.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,3 +687,10 @@ testPBKDF2('pass\0word', 'sa\0lt', 4096, 16,
687687
// Assume that we have at least AES256-SHA.
688688
assert.notEqual(0, crypto.getCiphers());
689689
assert.notEqual(-1, crypto.getCiphers().indexOf('AES256-SHA'));
690+
691+
// Assert that we have sha and sha1 but not SHA and SHA1.
692+
assert.notEqual(0, crypto.getHashes());
693+
assert.notEqual(-1, crypto.getHashes().indexOf('sha1'));
694+
assert.notEqual(-1, crypto.getHashes().indexOf('sha'));
695+
assert.equal(-1, crypto.getHashes().indexOf('SHA1'));
696+
assert.equal(-1, crypto.getHashes().indexOf('SHA'));

0 commit comments

Comments
 (0)