Skip to content

Commit

Permalink
Add OpenSSL::Digest.digests to get a list of available digests
Browse files Browse the repository at this point in the history
  • Loading branch information
bdewater committed Mar 15, 2024
1 parent 1e8e246 commit 4b17d37
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
33 changes: 31 additions & 2 deletions ext/openssl/ossl_digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ VALUE ossl_digest_update(VALUE, VALUE);
* Digest.new(string [, data]) -> Digest
*
* Creates a Digest instance based on _string_, which is either the ln
* (long name) or sn (short name) of a supported digest algorithm.
* (long name) or sn (short name) of a supported digest algorithm. A list of
* supported algorithms can be obtained by calling OpenSSL::Digest.digests.
*
* If _data_ (a String) is given, it is used as the initial input to the
* Digest instance, i.e.
Expand Down Expand Up @@ -162,6 +163,32 @@ ossl_digest_copy(VALUE self, VALUE other)
return self;
}

static void
add_digest_name_to_ary(const OBJ_NAME *name, void *arg)
{
VALUE ary = (VALUE)arg;
rb_ary_push(ary, rb_str_new2(name->name));
}

/*
* call-seq:
* OpenSSL::Digest.digests -> array[string...]
*
* Returns the names of all available digests in an array.
*/
static VALUE
ossl_s_digests(VALUE self)
{
VALUE ary;

ary = rb_ary_new();
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
add_digest_name_to_ary,
(void*)ary);

return ary;
}

/*
* call-seq:
* digest.reset -> self
Expand Down Expand Up @@ -245,7 +272,8 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
* call-seq:
* digest.name -> string
*
* Returns the sn of this Digest algorithm.
* Returns the short name of this Digest algorithm which may differ slightly
* from the original name provided.
*
* === Example
* digest = OpenSSL::Digest.new('SHA512')
Expand Down Expand Up @@ -412,6 +440,7 @@ Init_ossl_digest(void)

rb_define_alloc_func(cDigest, ossl_digest_alloc);

rb_define_module_function(cDigest, "digests", ossl_s_digests, 0);
rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1);
rb_define_method(cDigest, "initialize_copy", ossl_digest_copy, 1);
rb_define_method(cDigest, "reset", ossl_digest_reset, 0);
Expand Down
20 changes: 13 additions & 7 deletions test/openssl/test_digest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def test_sha2
end

def test_sha512_truncate
pend "SHA512_224 is not implemented" unless digest_available?('SHA512-224')
pend "SHA512_224 is not implemented" unless digest_available?('sha512-224')
sha512_224_a = "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327"
sha512_256_a = "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8"

Expand All @@ -100,7 +100,7 @@ def test_sha512_truncate
end

def test_sha3
pend "SHA3 is not implemented" unless digest_available?('SHA3-224')
pend "SHA3 is not implemented" unless digest_available?('sha3-224')
s224 = '6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7'
s256 = 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a'
s384 = '0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004'
Expand All @@ -126,6 +126,15 @@ def test_openssl_digest
end
end

def test_digests
digests = OpenSSL::Digest.digests
assert_kind_of Array, digests
assert_include digests, "md5"
assert_include digests, "sha1"
assert_include digests, "sha256"
assert_include digests, "sha512"
end

private

def check_digest(oid)
Expand All @@ -138,11 +147,8 @@ def check_digest(oid)
end

def digest_available?(name)
begin
OpenSSL::Digest.new(name)
rescue RuntimeError
false
end
@digests ||= OpenSSL::Digest.digests
@digests.include?(name)
end
end

Expand Down

0 comments on commit 4b17d37

Please sign in to comment.