Skip to content
20 changes: 20 additions & 0 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,23 @@ ossl_pkey_decrypt(int argc, VALUE *argv, VALUE self)
return str;
}


/*
* Returns bit length of the PKEy
*/
static VALUE
ossl_pkey_length_in_bits(VALUE self)
{
EVP_PKEY * pkey;
int bits;

GetPKey(self, pkey);

bits = EVP_PKEY_get_bits(pkey);
return INT2NUM(bits);

}

/*
* INIT
*/
Expand Down Expand Up @@ -1785,6 +1802,9 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "encrypt", ossl_pkey_encrypt, -1);
rb_define_method(cPKey, "decrypt", ossl_pkey_decrypt, -1);


rb_define_method(cPKey, "keysize_in_bits", ossl_pkey_length_in_bits, 0);

id_private_q = rb_intern("private?");

/*
Expand Down
1 change: 1 addition & 0 deletions test/openssl/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def test_generic_oid_inspect
assert_instance_of OpenSSL::PKey::PKey, x25519
assert_equal "X25519", x25519.oid
assert_match %r{oid=X25519}, x25519.inspect
assert_equal 253, x25519.keysize_in_bits
end

def test_s_generate_parameters
Expand Down
3 changes: 3 additions & 0 deletions test/openssl/test_pkey_dh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def test_derive_key
assert_equal z, dh1.derive(dh2_pub)
assert_equal z, dh2.derive(dh1_pub)

assert_equal(1024, dh1.keysize_in_bits)
assert_equal(1024, dh2.keysize_in_bits)

assert_raise(OpenSSL::PKey::PKeyError) { params.derive(dh1_pub) }
assert_raise(OpenSSL::PKey::PKeyError) { dh1_pub.derive(params) }

Expand Down
3 changes: 3 additions & 0 deletions test/openssl/test_pkey_ec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,19 @@ def test_check_key
assert_equal(true, key0.check_key)
assert_equal(true, key0.private?)
assert_equal(true, key0.public?)
assert_equal(256, key0.keysize_in_bits)

key1 = OpenSSL::PKey.read(key0.public_to_der)
assert_equal(true, key1.check_key)
assert_equal(false, key1.private?)
assert_equal(true, key1.public?)
assert_equal(256, key1.keysize_in_bits)

key2 = OpenSSL::PKey.read(key0.private_to_der)
assert_equal(true, key2.private?)
assert_equal(true, key2.public?)
assert_equal(true, key2.check_key)
assert_equal(256, key2.keysize_in_bits)

# Behavior of EVP_PKEY_public_check changes between OpenSSL 1.1.1 and 3.0
key4 = Fixtures.pkey("p256_too_large")
Expand Down