mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
openssl: fix equality test methods of OpenSSL::BN
* ext/openssl/ossl_bn.c (try_convert_to_bnptr): Extracted from GetBNPtr(). This doesn't raise exception but returns NULL on error. (GetBNPtr): Raise TypeError if conversion fails. (ossl_bn_eq): Implement BN#==. (ossl_bn_eql): #eql? should not raise TypeError even if the argument is not compatible with BN. (ossl_bn_hash): Implement BN#hash. * ext/openssl/ossl_bn.c (Init_ossl_bn): Define #== and #hash. * test/openssl/test_bn.rb: Test BN#eql?, #== and #hash git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55047 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2bedfc6627
commit
b43fd8e080
3 changed files with 103 additions and 17 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Wed May 18 11:19:59 2016 Kazuki Yamaguchi <k@rhe.jp>
|
||||||
|
|
||||||
|
* ext/openssl/ossl_bn.c (try_convert_to_bnptr): Extracted from
|
||||||
|
GetBNPtr(). This doesn't raise exception but returns NULL on error.
|
||||||
|
(GetBNPtr): Raise TypeError if conversion fails.
|
||||||
|
(ossl_bn_eq): Implement BN#==.
|
||||||
|
(ossl_bn_eql): #eql? should not raise TypeError even if the argument
|
||||||
|
is not compatible with BN.
|
||||||
|
(ossl_bn_hash): Implement BN#hash.
|
||||||
|
|
||||||
|
* ext/openssl/ossl_bn.c (Init_ossl_bn): Define #== and #hash.
|
||||||
|
|
||||||
|
* test/openssl/test_bn.rb: Test BN#eql?, #== and #hash
|
||||||
|
|
||||||
Wed May 18 10:17:41 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed May 18 10:17:41 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* include/ruby/ruby.h (RB_INTEGER_TYPE_P): new macro and
|
* include/ruby/ruby.h (RB_INTEGER_TYPE_P): new macro and
|
||||||
|
|
|
@ -82,8 +82,8 @@ ossl_bn_new(const BIGNUM *bn)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
BIGNUM *
|
static BIGNUM *
|
||||||
GetBNPtr(VALUE obj)
|
try_convert_to_bnptr(VALUE obj)
|
||||||
{
|
{
|
||||||
BIGNUM *bn = NULL;
|
BIGNUM *bn = NULL;
|
||||||
VALUE newobj;
|
VALUE newobj;
|
||||||
|
@ -100,14 +100,20 @@ GetBNPtr(VALUE obj)
|
||||||
}
|
}
|
||||||
SetBN(newobj, bn); /* Handle potencial mem leaks */
|
SetBN(newobj, bn); /* Handle potencial mem leaks */
|
||||||
break;
|
break;
|
||||||
case T_NIL:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
|
|
||||||
}
|
}
|
||||||
return bn;
|
return bn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIGNUM *
|
||||||
|
GetBNPtr(VALUE obj)
|
||||||
|
{
|
||||||
|
BIGNUM *bn = try_convert_to_bnptr(obj);
|
||||||
|
if (!bn)
|
||||||
|
ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
|
||||||
|
|
||||||
|
return bn;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private
|
* Private
|
||||||
*/
|
*/
|
||||||
|
@ -841,18 +847,75 @@ BIGNUM_CMP(ucmp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* big.eql?(obj) => true or false
|
* bn == obj => true or false
|
||||||
|
*
|
||||||
|
* Returns +true+ only if +obj+ has the same value as +bn+. Contrast this
|
||||||
|
* with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_bn_eq(VALUE self, VALUE other)
|
||||||
|
{
|
||||||
|
BIGNUM *bn1, *bn2;
|
||||||
|
|
||||||
|
GetBN(self, bn1);
|
||||||
|
/* BNPtr may raise, so we can't use here */
|
||||||
|
bn2 = try_convert_to_bnptr(other);
|
||||||
|
|
||||||
|
if (bn2 && !BN_cmp(bn1, bn2)) {
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* bn.eql?(obj) => true or false
|
||||||
*
|
*
|
||||||
* Returns <code>true</code> only if <i>obj</i> is a
|
* Returns <code>true</code> only if <i>obj</i> is a
|
||||||
* <code>Bignum</code> with the same value as <i>big</i>. Contrast this
|
* <code>OpenSSL::BN</code> with the same value as <i>big</i>. Contrast this
|
||||||
|
* with OpenSSL::BN#==, which performs type conversions.
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_bn_eql(VALUE self, VALUE other)
|
ossl_bn_eql(VALUE self, VALUE other)
|
||||||
{
|
{
|
||||||
if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
|
BIGNUM *bn1, *bn2;
|
||||||
return Qtrue;
|
|
||||||
|
if (!rb_obj_is_kind_of(other, cBN))
|
||||||
|
return Qfalse;
|
||||||
|
GetBN(self, bn1);
|
||||||
|
GetBN(other, bn2);
|
||||||
|
|
||||||
|
return BN_cmp(bn1, bn2) ? Qfalse : Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* bn.hash => Integer
|
||||||
|
*
|
||||||
|
* Returns a hash code for this object.
|
||||||
|
*
|
||||||
|
* See also Object#hash.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_bn_hash(VALUE self)
|
||||||
|
{
|
||||||
|
BIGNUM *bn;
|
||||||
|
VALUE hash;
|
||||||
|
unsigned char *buf;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
GetBN(self, bn);
|
||||||
|
len = BN_num_bytes(bn);
|
||||||
|
buf = xmalloc(len);
|
||||||
|
if (BN_bn2bin(bn, buf) != len) {
|
||||||
|
xfree(buf);
|
||||||
|
ossl_raise(eBNError, NULL);
|
||||||
}
|
}
|
||||||
return Qfalse;
|
|
||||||
|
hash = INT2FIX(rb_memhash(buf, len));
|
||||||
|
xfree(buf);
|
||||||
|
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -982,8 +1045,9 @@ Init_ossl_bn(void)
|
||||||
rb_define_alias(cBN, "<=>", "cmp");
|
rb_define_alias(cBN, "<=>", "cmp");
|
||||||
rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
|
rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
|
||||||
rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
|
rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
|
||||||
rb_define_alias(cBN, "==", "eql?");
|
rb_define_method(cBN, "hash", ossl_bn_hash, 0);
|
||||||
rb_define_alias(cBN, "===", "eql?");
|
rb_define_method(cBN, "==", ossl_bn_eq, 1);
|
||||||
|
rb_define_alias(cBN, "===", "==");
|
||||||
rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
|
rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
|
||||||
rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
|
rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
|
||||||
/* is_word */
|
/* is_word */
|
||||||
|
|
|
@ -43,10 +43,18 @@ class OpenSSL::TestBN < Test::Unit::TestCase
|
||||||
assert_equal(true, OpenSSL::BN.new((2 ** 127 - 1).to_s(16), 16).prime?(1))
|
assert_equal(true, OpenSSL::BN.new((2 ** 127 - 1).to_s(16), 16).prime?(1))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cmp_nil
|
def test_cmp
|
||||||
bn = OpenSSL::BN.new('1')
|
bn1 = OpenSSL::BN.new('1')
|
||||||
assert_equal(false, bn == nil)
|
bn2 = OpenSSL::BN.new('1')
|
||||||
assert_equal(true, bn != nil)
|
bn3 = OpenSSL::BN.new('2')
|
||||||
|
assert_equal(false, bn1 == nil)
|
||||||
|
assert_equal(true, bn1 != nil)
|
||||||
|
assert_equal(true, bn1 == bn2)
|
||||||
|
assert_equal(false, bn1 == bn3)
|
||||||
|
assert_equal(true, bn1.eql?(bn2))
|
||||||
|
assert_equal(false, bn1.eql?(bn3))
|
||||||
|
assert_equal(bn1.hash, bn2.hash)
|
||||||
|
assert_not_equal(bn3.hash, bn1.hash)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue