aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart de Water <bartdewater@gmail.com>2019-11-03 10:18:36 -0500
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2019-11-04 06:55:39 +0900
commit664ba349e7a6995679e65db8deac6d11652f4697 (patch)
tree1da70bf8dac72fd7ed14201101437ade9101cc87
parent18a5b5e5ee6b937eccaab090eb4e5f82c8737fb7 (diff)
downloadruby-openssl-664ba349e7a6995679e65db8deac6d11652f4697.tar.gz
Make OpenSSL::HMAC#== compare in constant time instead of returning false
-rw-r--r--ext/openssl/ossl_hmac.c12
-rw-r--r--lib/openssl.rb1
-rw-r--r--lib/openssl/hmac.rb13
-rw-r--r--test/test_hmac.rb10
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