From 0b8db854a4c595826eeec11aa03ab20f242f651e Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Fri, 13 May 2016 15:36:43 +0900 Subject: ext/openssl: implement OpenSSL::PKey::{DSA,RSA,EC}#public_pkey Add OpenSSL::PKey::{DSA,RSA,EC}#public_pkey. They return a new instance of itself, which contains only parameters and public information. The old methods, {DSA,RSA}#public_key, are now deprecated. There are 3 types of PKey#public_key: 1) EC#public_key, which returns the actual public key (EC::Point). 2) RSA/DSA#public_key, which returns a new instance of PKey with no private information. 3) DH#public_key, which returns a new instance of DH which contains only DH params. This doesn't even contain 'private key'. This is very confusing. The new methods are intend to replace the 2). --- ext/openssl/ossl_pkey_dsa.c | 18 +++++++++++------- ext/openssl/ossl_pkey_ec.c | 25 +++++++++++++++++++++++++ ext/openssl/ossl_pkey_rsa.c | 11 ++++++++--- 3 files changed, 44 insertions(+), 10 deletions(-) (limited to 'ext/openssl') diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 04900cc649..592b03ae3d 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -261,7 +261,8 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) * dsa.public? -> true | false * * Indicates whether this DSA instance has a public key associated with it or - * not. The public key may be retrieved with DSA#public_key. + * not. An DSA instance that contains only public key may be retrieved with + * DSA#public_pkey. */ static VALUE ossl_dsa_is_public(VALUE self) @@ -278,7 +279,7 @@ ossl_dsa_is_public(VALUE self) * dsa.private? -> true | false * * Indicates whether this DSA instance has a private key associated with it or - * not. The private key may be retrieved with DSA#private_key. + * not. */ static VALUE ossl_dsa_is_private(VALUE self) @@ -436,7 +437,7 @@ ossl_dsa_to_text(VALUE self) /* * call-seq: - * dsa.public_key -> aDSA + * dsa.public_pkey -> aDSA * * Returns a new DSA instance that carries just the public key information. * If the current instance has also private key information, this will no @@ -446,13 +447,15 @@ ossl_dsa_to_text(VALUE self) * * === Example * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information - * pub_key = dsa.public_key # has only the public part available + * pub_key = dsa.public_pkey # has only the public part available * pub_key_der = pub_key.to_der # it's safe to publish this * - * + * === Note + * This method was renamed from OpenSSL::PKey::DSA#public_key. It remains as + * an alias. */ static VALUE -ossl_dsa_to_public_key(VALUE self) +ossl_dsa_to_public_pkey(VALUE self) { EVP_PKEY *pkey; DSA *dsa; @@ -603,7 +606,8 @@ Init_ossl_dsa(void) rb_define_alias(cDSA, "to_pem", "export"); rb_define_alias(cDSA, "to_s", "export"); rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0); - rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0); + rb_define_method(cDSA, "public_pkey", ossl_dsa_to_public_pkey, 0); + rb_define_alias(cDSA, "public_key", "public_pkey"); rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index bbdd8a7a5d..80c241aca1 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -630,6 +630,30 @@ static VALUE ossl_ec_key_check_key(VALUE self) return Qtrue; } +/* + * call-seq: + * key.public_pkey => OpenSSL::PKey::EC + * + * Returns a new EC instance that has only public information. + */ +static VALUE ossl_ec_key_public_pkey(VALUE self) +{ + EC_KEY *ec, *ec_new; + + Require_EC_KEY(self, ec); + + if (!EC_KEY_get0_public_key(ec)) + ossl_raise(eECError, "public key is not set"); + + ec_new = EC_KEY_dup(ec); + if (!ec_new) + ossl_raise(eECError, "EC_KEY_dup"); + + EC_KEY_set_private_key(ec_new, NULL); + + return ec_instance(cEC, ec_new); +} + /* * call-seq: * key.dh_compute_key(pubkey) => String @@ -1634,6 +1658,7 @@ void Init_ossl_ec(void) */ rb_define_method(cEC, "generate_key", ossl_ec_key_generate_key, 0); rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0); + rb_define_method(cEC, "public_pkey", ossl_ec_key_public_pkey, 0); rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1); rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1); diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 20b993abb8..bb51453442 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -562,12 +562,16 @@ ossl_rsa_to_text(VALUE self) /* * call-seq: - * rsa.public_key -> RSA + * rsa.public_pkey -> RSA * * Makes new RSA instance containing the public key from the private key. + * + * === Note + * This method was renamed from OpenSSL::PKey::RSA#public_key. It remains as + * an alias. */ static VALUE -ossl_rsa_to_public_key(VALUE self) +ossl_rsa_to_public_pkey(VALUE self) { EVP_PKEY *pkey; RSA *rsa; @@ -664,7 +668,8 @@ Init_ossl_rsa(void) rb_define_alias(cRSA, "to_pem", "export"); rb_define_alias(cRSA, "to_s", "export"); rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); - rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0); + rb_define_method(cRSA, "public_pkey", ossl_rsa_to_public_pkey, 0); + rb_define_alias(cRSA, "public_key", "public_pkey"); rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); -- cgit v1.2.3