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>
|
||||
|
||||
* include/ruby/ruby.h (RB_INTEGER_TYPE_P): new macro and
|
||||
|
|
|
@ -82,8 +82,8 @@ ossl_bn_new(const BIGNUM *bn)
|
|||
return obj;
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
GetBNPtr(VALUE obj)
|
||||
static BIGNUM *
|
||||
try_convert_to_bnptr(VALUE obj)
|
||||
{
|
||||
BIGNUM *bn = NULL;
|
||||
VALUE newobj;
|
||||
|
@ -100,14 +100,20 @@ GetBNPtr(VALUE obj)
|
|||
}
|
||||
SetBN(newobj, bn); /* Handle potencial mem leaks */
|
||||
break;
|
||||
case T_NIL:
|
||||
break;
|
||||
default:
|
||||
ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::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
|
||||
*/
|
||||
|
@ -841,18 +847,75 @@ BIGNUM_CMP(ucmp)
|
|||
|
||||
/*
|
||||
* 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
|
||||
* <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
|
||||
ossl_bn_eql(VALUE self, VALUE other)
|
||||
{
|
||||
if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
|
||||
return Qtrue;
|
||||
}
|
||||
BIGNUM *bn1, *bn2;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_method(cBN, "ucmp", ossl_bn_ucmp, 1);
|
||||
rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
|
||||
rb_define_alias(cBN, "==", "eql?");
|
||||
rb_define_alias(cBN, "===", "eql?");
|
||||
rb_define_method(cBN, "hash", ossl_bn_hash, 0);
|
||||
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, "one?", ossl_bn_is_one, 0);
|
||||
/* 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))
|
||||
end
|
||||
|
||||
def test_cmp_nil
|
||||
bn = OpenSSL::BN.new('1')
|
||||
assert_equal(false, bn == nil)
|
||||
assert_equal(true, bn != nil)
|
||||
def test_cmp
|
||||
bn1 = OpenSSL::BN.new('1')
|
||||
bn2 = OpenSSL::BN.new('1')
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue