diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index a897c86b6..b2eef485b 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -159,6 +159,7 @@ def find_openssl_library have_func("EVP_MD_CTX_get_pkey_ctx(NULL)", evp_h) have_func("EVP_PKEY_eq(NULL, NULL)", evp_h) have_func("EVP_PKEY_dup(NULL)", evp_h) +have_func("EVP_PKEY_get_size", evp_h) # added in 3.2.0 have_func("SSL_get0_group_name(NULL)", ssl_h) diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 6592f9cce..331e3cec9 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -29,4 +29,8 @@ # define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b) #endif +#ifndef HAVE_EVP_PKEY_GET_SIZE +# define EVP_PKEY_get_size(x) EVP_PKEY_size(x) +#endif + #endif /* _OSSL_OPENSSL_MISSING_H_ */ diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index d2fd5b29c..fafc1d44b 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -1074,6 +1074,28 @@ ossl_pkey_compare(VALUE self, VALUE other) ossl_raise(ePKeyError, "EVP_PKEY_eq"); } +/* + * call-seq: + * pkey.size -> integer + * + * Get the key size in bytes + * + * == Example + * rsa_key = OpenSSL::PKey::RSA.new(pem_encoded_private_key) + * + * rsa_key.size => 512 + */ +static VALUE +ossl_pkey_size(VALUE self) { + int ret = 0; + EVP_PKEY *selfPKey; + + GetPKey(self, selfPKey); + ret = EVP_PKEY_get_size(selfPKey); + + return INT2NUM(ret); +} + /* * call-seq: * pkey.sign(digest, data [, options]) -> string @@ -1760,6 +1782,7 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0); rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0); rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); + rb_define_method(cPKey, "size", ossl_pkey_size, 0); rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); rb_define_method(cPKey, "verify", ossl_pkey_verify, -1); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 88299888f..d8c69c581 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -310,6 +310,20 @@ def test_compare? end end + def test_size + key1 = Fixtures.pkey("rsa-1") + key2 = Fixtures.pkey("rsa-2") + key3 = Fixtures.pkey("p256") + + assert_equal(512, key1.size) + assert_equal(512, key2.size) + assert_equal(72, key3.size) + + # Should match the number of bits of the public component for RSA keys + assert_equal(key1.n.num_bits / 8, key1.size) + assert_equal(key1.n.num_bits / 8, key2.size) + end + def test_to_text rsa = Fixtures.pkey("rsa-1") assert_include rsa.to_text, "publicExponent"