Feature #10098 » hmac-timing.patch
ext/openssl/ossl_hmac.c | ||
---|---|---|
}
|
||
/*
|
||
* call-seq:
|
||
* hmac.verify(bytes) -> aBoolean
|
||
*
|
||
* Compares the receiver's digest to another digest in a timing-safe way.
|
||
* +bytes+ must be a binary string containing a digest, for example by calling +#digest+ on another
|
||
* instance of +OpenSSL::Digest+.
|
||
*/
|
||
VALUE
|
||
ossl_hmac_verify(VALUE self, VALUE other)
|
||
{
|
||
HMAC_CTX *ctx;
|
||
unsigned char *buf;
|
||
unsigned int buf_len;
|
||
unsigned char result;
|
||
unsigned int cur_idx;
|
||
unsigned char *other_buf;
|
||
if (!RB_TYPE_P(other, T_STRING))
|
||
rb_raise(rb_eArgError, "Must supply binary string or instance of OpenSSL::HMAC");
|
||
GetHMAC(self, ctx);
|
||
hmac_final(ctx, &buf, &buf_len);
|
||
if (!buf_len || buf_len != RSTRING_LEN(other))
|
||
return Qfalse;
|
||
other_buf = (unsigned char *)RSTRING_PTR(other);
|
||
result = 0;
|
||
for (cur_idx = 0; cur_idx < buf_len; cur_idx++) {
|
||
result |= buf[cur_idx] ^ other_buf[cur_idx];
|
||
}
|
||
if (result == 0)
|
||
return Qtrue;
|
||
return Qfalse;
|
||
}
|
||
/*
|
||
* INIT
|
||
*/
|
||
void
|
||
... | ... | |
rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0);
|
||
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
||
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
||
rb_define_method(cHMAC, "verify", ossl_hmac_verify, 1);
|
||
}
|
||
#else /* NO_HMAC */
|
test/openssl/test_hmac.rb | ||
---|---|---|
assert_equal(OpenSSL::HMAC.digest("MD5", @key, @data), @h2.digest, "digest")
|
||
assert_equal(OpenSSL::HMAC.hexdigest("MD5", @key, @data), @h2.hexdigest, "hexdigest")
|
||
assert_same(false, @h1.verify("\x9EPYl\x0F\xA1\x19\x7F\x85\x87D:\x94-\x8A\xFD"))
|
||
assert_same(true, @h1.verify("\x9EPYl\x0F\xA1\x19\x7F\x85\x87D:\x94-\x8A\xFC"))
|
||
end
|
||
def test_hmac_verify
|
||
end
|
||
def test_dup
|