Skip to content

Add OpenSSL::Digest.digests to get a list of available digests #726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ext/openssl/ossl_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,8 @@ ossl_cipher_final(VALUE self)
* call-seq:
* cipher.name -> string
*
* Returns the name of the cipher which may differ slightly from the original
* name provided.
* Returns the short name of the cipher which may differ slightly from the
* original name provided.
*/
static VALUE
ossl_cipher_name(VALUE self)
Expand Down
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