diff options
author | Bart de Water <bartdewater@gmail.com> | 2019-11-03 10:18:36 -0500 |
---|---|---|
committer | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2019-11-04 06:55:39 +0900 |
commit | 664ba349e7a6995679e65db8deac6d11652f4697 (patch) | |
tree | 1da70bf8dac72fd7ed14201101437ade9101cc87 | |
parent | 18a5b5e5ee6b937eccaab090eb4e5f82c8737fb7 (diff) | |
download | ruby-openssl-664ba349e7a6995679e65db8deac6d11652f4697.tar.gz |
Make OpenSSL::HMAC#== compare in constant time instead of returning false
-rw-r--r-- | ext/openssl/ossl_hmac.c | 12 | ||||
-rw-r--r-- | lib/openssl.rb | 1 | ||||
-rw-r--r-- | lib/openssl/hmac.rb | 13 | ||||
-rw-r--r-- | test/test_hmac.rb | 10 |
4 files changed, 26 insertions, 10 deletions
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index 757754cd..2ac2e5c6 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -84,20 +84,12 @@ ossl_hmac_alloc(VALUE klass) * * === A note about comparisons * - * Two instances won't be equal when they're compared, even if they have the - * same value. For example: + * Two instances can be securely compared with #== in constant time: * * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * instance == other_instance - * #=> false - * - * Use #digest and compare in constant time: - * - * OpenSSL.fixed_length_secure_compare(instance.digest, other_instance.digest) - * #=> true + * #=> true * */ static VALUE diff --git a/lib/openssl.rb b/lib/openssl.rb index ec143bc7..be296955 100644 --- a/lib/openssl.rb +++ b/lib/openssl.rb @@ -17,6 +17,7 @@ require_relative 'openssl/pkey' require_relative 'openssl/cipher' require_relative 'openssl/config' require_relative 'openssl/digest' +require_relative 'openssl/hmac' require_relative 'openssl/x509' require_relative 'openssl/ssl' require_relative 'openssl/pkcs5' diff --git a/lib/openssl/hmac.rb b/lib/openssl/hmac.rb new file mode 100644 index 00000000..3d442761 --- /dev/null +++ b/lib/openssl/hmac.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module OpenSSL + class HMAC + # Securely compare with another HMAC instance in constant time. + def ==(other) + return false unless HMAC === other + return false unless self.digest.bytesize == other.digest.bytesize + + OpenSSL.fixed_length_secure_compare(self.digest, other.digest) + end + end +end diff --git a/test/test_hmac.rb b/test/test_hmac.rb index 831a5b6b..4cd177b8 100644 --- a/test/test_hmac.rb +++ b/test/test_hmac.rb @@ -39,6 +39,16 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase second = h1.update("test").hexdigest assert_equal first, second end + + def test_eq + h1 = OpenSSL::HMAC.new("KEY", "MD5") + h2 = OpenSSL::HMAC.new("KEY", OpenSSL::Digest.new("MD5")) + h3 = OpenSSL::HMAC.new("FOO", "MD5") + + assert_equal h1, h2 + refute_equal h1, h2.digest + refute_equal h1, h3 + end end end |