From 13d5616d17763c018a3c3428e6e408fbb4c70c64 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sat, 15 Aug 2026 01:19:18 +0900 Subject: [PATCH] pkey: avoid using {DH,DSA,RSA}#public_key in docs and tests As documented, the #public_key methods on OpenSSL::PKey::{DH,DSA,RSA} are obsolete, as their behavior is inconsistent and better alternatives are available. Remove unnecessary uses from RDoc comments for other methods. Also add dedicated tests for these methods to confirm the current behavior. --- ext/openssl/ossl.c | 6 +++--- ext/openssl/ossl_ns_spki.c | 2 +- ext/openssl/ossl_pkey.c | 4 ++-- ext/openssl/ossl_x509cert.c | 4 ++-- test/openssl/test_ns_spki.rb | 12 ++++++------ test/openssl/test_pkey_dsa.rb | 24 ++++++++++++++++++------ test/openssl/test_pkey_rsa.rb | 27 +++++++++++++++++---------- 7 files changed, 49 insertions(+), 30 deletions(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 6438d96fd..d14265c09 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -754,7 +754,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * cert.not_before = Time.now * cert.not_after = Time.now + 3600 * - * cert.public_key = key.public_key + * cert.public_key = key * cert.subject = name * * === Certificate Extensions @@ -836,7 +836,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * ca_cert.not_before = Time.now * ca_cert.not_after = Time.now + 86400 * - * ca_cert.public_key = ca_key.public_key + * ca_cert.public_key = ca_key * ca_cert.subject = ca_name * ca_cert.issuer = ca_name * @@ -878,7 +878,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * csr = OpenSSL::X509::Request.new * csr.version = 0 * csr.subject = name - * csr.public_key = key.public_key + * csr.public_key = key * csr.sign key, OpenSSL::Digest.new('SHA1') * * A CSR is saved to disk and sent to the CA for signing. diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index eb9933948..eb4fce596 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -336,7 +336,7 @@ ossl_spki_verify(VALUE self, VALUE key) * key = OpenSSL::PKey::RSA.new 2048 * spki = OpenSSL::Netscape::SPKI.new * spki.challenge = "RandomChallenge" - * spki.public_key = key.public_key + * spki.public_key = key * spki.sign(key, OpenSSL::Digest.new('SHA256')) * #send a request containing this to a server generating a certificate * === Verifying an SPKI request diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 5cbc0d195..7528d2d26 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -1192,7 +1192,7 @@ ossl_pkey_compare(VALUE self, VALUE other) * signature = pkey.sign("SHA256", data, signopts) * * # Creates a copy of the RSA key pkey, but without the private components - * pub_key = pkey.public_key + * pub_key = OpenSSL::PKey.read(pkey.public_to_der) * puts pub_key.verify("SHA256", signature, data, signopts) # => true */ static VALUE @@ -1350,7 +1350,7 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self) * signature = pkey.sign_raw("SHA256", hash, signopts) * * # Creates a copy of the RSA key pkey, but without the private components - * pub_key = pkey.public_key + * pub_key = OpenSSL::PKey.read(pkey.public_to_der) * puts pub_key.verify_raw("SHA256", signature, hash, signopts) # => true */ static VALUE diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index b40387194..f0a3a8157 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -922,7 +922,7 @@ Init_ossl_x509cert(void) * root_ca.serial = 1 * root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA" * root_ca.issuer = root_ca.subject # root CA's are "self-signed" - * root_ca.public_key = root_key.public_key + * root_ca.public_key = root_key * root_ca.not_before = Time.now * root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity * ef = OpenSSL::X509::ExtensionFactory.new @@ -943,7 +943,7 @@ Init_ossl_x509cert(void) * cert.serial = 2 * cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate" * cert.issuer = root_ca.subject # root CA is the issuer - * cert.public_key = key.public_key + * cert.public_key = key * cert.not_before = Time.now * cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity * ef = OpenSSL::X509::ExtensionFactory.new diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb index 048442928..2607a8c0b 100644 --- a/test/openssl/test_ns_spki.rb +++ b/test/openssl/test_ns_spki.rb @@ -21,17 +21,17 @@ def test_build_data key2 = Fixtures.pkey("rsa-2") spki = OpenSSL::Netscape::SPKI.new spki.challenge = "RandomString" - spki.public_key = key1.public_key + spki.public_key = key1 spki.sign(key1, OpenSSL::Digest.new('SHA256')) - assert(spki.verify(spki.public_key)) - assert(spki.verify(key1.public_key)) - assert(!spki.verify(key2.public_key)) + assert_true(spki.verify(spki.public_key)) + assert_true(spki.verify(OpenSSL::PKey.read(key1.public_to_der))) + assert_false(spki.verify(OpenSSL::PKey.read(key2.public_to_der))) der = spki.to_der spki = OpenSSL::Netscape::SPKI.new(der) assert_equal("RandomString", spki.challenge) - assert_equal(key1.public_key.to_der, spki.public_key.to_der) - assert(spki.verify(spki.public_key)) + assert_equal(key1.public_to_der, spki.public_key.public_to_der) + assert_true(spki.verify(spki.public_key)) assert_not_nil(spki.to_text) end diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb index 1ec0bf0b4..fb692854a 100644 --- a/test/openssl/test_pkey_dsa.rb +++ b/test/openssl/test_pkey_dsa.rb @@ -14,16 +14,15 @@ def test_private assert_equal true, key.private? key2 = OpenSSL::PKey::DSA.new(key.to_der) assert_equal true, key2.private? - key3 = key.public_key + key3 = OpenSSL::PKey::DSA.new(key.public_to_der) assert_equal false, key3.private? - key4 = OpenSSL::PKey::DSA.new(key3.to_der) - assert_equal false, key4.private? end def test_new - key = OpenSSL::PKey::DSA.new(2048) - pem = key.public_key.to_pem - OpenSSL::PKey::DSA.new pem + key = OpenSSL::PKey::DSA.new(1024) + assert_predicate(key, :private?) + assert_equal(1024, key.p.num_bits) + assert_equal(160, key.q.num_bits) end def test_new_break @@ -233,6 +232,19 @@ def test_params assert_nil(pubkey.params["priv_key"]) end + def test_public_key + key = Fixtures.pkey("dsa2048") + pub = key.public_key + assert_not_predicate(pub, :private?) + assert_predicate(pub, :public?) + assert_equal(key.p, pub.p) + assert_equal(key.q, pub.q) + assert_equal(key.g, pub.g) + assert_equal(key.pub_key, pub.pub_key) + assert_nil(pub.priv_key) + assert_equal(key.public_to_der, pub.to_der) + end + def test_dup key = Fixtures.pkey("dsa2048") key2 = key.dup diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb index d56d19bd9..31c3c52b3 100644 --- a/test/openssl/test_pkey_rsa.rb +++ b/test/openssl/test_pkey_rsa.rb @@ -20,13 +20,9 @@ def test_private key2 = OpenSSL::PKey::RSA.new(key.to_der) assert_true(key2.private?) - # public key - key3 = key.public_key - assert_false(key3.private?) - # Generated by public key DER - key4 = OpenSSL::PKey::RSA.new(key3.to_der) - assert_false(key4.private?) + key3 = OpenSSL::PKey::RSA.new(key.public_to_der) + assert_false(key3.private?) if !openssl?(3, 0, 0) # Generated by RSA#set_key @@ -290,11 +286,11 @@ def test_export # key has only n, e and d key.set_key(orig.n, orig.e, orig.d) - assert_equal orig.public_key.export, key.export + assert_equal pub.export, key.export # key has only n, e, d, p and q key.set_factors(orig.p, orig.q) - assert_equal orig.public_key.export, key.export + assert_equal pub.export, key.export # key has n, e, d, p, q, dmp1, dmq1 and iqmp key.set_crt_params(orig.dmp1, orig.dmq1, orig.iqmp) @@ -315,11 +311,11 @@ def test_to_der # key has only n, e and d key.set_key(orig.n, orig.e, orig.d) - assert_equal orig.public_key.to_der, key.to_der + assert_equal pub.to_der, key.to_der # key has only n, e, d, p and q key.set_factors(orig.p, orig.q) - assert_equal orig.public_key.to_der, key.to_der + assert_equal pub.to_der, key.to_der # key has n, e, d, p, q, dmp1, dmq1 and iqmp key.set_crt_params(orig.dmp1, orig.dmq1, orig.iqmp) @@ -548,6 +544,17 @@ def test_get_param assert_equal(key.iqmp, key.get_param("rsa-coefficient1")) end + def test_public_key + key = Fixtures.pkey("rsa-1") + pub = key.public_key + assert_not_predicate(pub, :private?) + assert_predicate(pub, :public?) + assert_equal(key.n, pub.n) + assert_equal(key.e, pub.e) + assert_nil(pub.d) + assert_equal(key.public_to_der, pub.to_der) + end + def test_dup key = Fixtures.pkey("rsa-1") key2 = key.dup