1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/openssl] pkey: implement #to_text using EVP API

Use EVP_PKEY_print_private() instead of the low-level API *_print()
functions, such as RSA_print().

EVP_PKEY_print_*() family was added in OpenSSL 1.0.0.

Note that it falls back to EVP_PKEY_print_public() and
EVP_PKEY_print_params() as necessary. This is required for EVP_PKEY_DH
type for which _private() fails if the private component is not set in
the pkey object.

Since the new API works in the same way for all key types, we now
implement #to_text in the base class OpenSSL::PKey::PKey rather than in
each subclass.

https://github.com/ruby/openssl/commit/e0b4c56956
This commit is contained in:
Kazuki Yamaguchi 2020-05-17 18:25:38 +09:00
parent 436aecb520
commit 5d1693aac5
6 changed files with 43 additions and 116 deletions

View file

@ -539,6 +539,43 @@ ossl_pkey_inspect(VALUE self)
OBJ_nid2sn(nid)); OBJ_nid2sn(nid));
} }
/*
* call-seq:
* pkey.to_text -> string
*
* Dumps key parameters, public key, and private key components contained in
* the key into a human-readable text.
*
* This is intended for debugging purpose.
*
* See also the man page EVP_PKEY_print_private(3).
*/
static VALUE
ossl_pkey_to_text(VALUE self)
{
EVP_PKEY *pkey;
BIO *bio;
GetPKey(self, pkey);
if (!(bio = BIO_new(BIO_s_mem())))
ossl_raise(ePKeyError, "BIO_new");
if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1)
goto out;
OSSL_BIO_reset(bio);
if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1)
goto out;
OSSL_BIO_reset(bio);
if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1)
goto out;
BIO_free(bio);
ossl_raise(ePKeyError, "EVP_PKEY_print_params");
out:
return ossl_membio2str(bio);
}
VALUE VALUE
ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der)
{ {
@ -1077,6 +1114,7 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); rb_define_method(cPKey, "oid", ossl_pkey_oid, 0);
rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0);
rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0);
rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1);
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);

View file

@ -266,34 +266,6 @@ ossl_dh_get_params(VALUE self)
return hash; return hash;
} }
/*
* call-seq:
* dh.to_text -> aString
*
* Prints all parameters of key to buffer
* INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
* Don't use :-)) (I's up to you)
*/
static VALUE
ossl_dh_to_text(VALUE self)
{
DH *dh;
BIO *out;
VALUE str;
GetDH(self, dh);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDHError, NULL);
}
if (!DHparams_print(out, dh)) {
BIO_free(out);
ossl_raise(eDHError, NULL);
}
str = ossl_membio2str(out);
return str;
}
/* /*
* call-seq: * call-seq:
* dh.public_key -> aDH * dh.public_key -> aDH
@ -426,7 +398,6 @@ Init_ossl_dh(void)
rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
rb_define_method(cDH, "public?", ossl_dh_is_public, 0); rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
rb_define_method(cDH, "private?", ossl_dh_is_private, 0); rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
rb_define_method(cDH, "export", ossl_dh_export, 0); rb_define_method(cDH, "export", ossl_dh_export, 0);
rb_define_alias(cDH, "to_pem", "export"); rb_define_alias(cDH, "to_pem", "export");
rb_define_alias(cDH, "to_s", "export"); rb_define_alias(cDH, "to_s", "export");

View file

@ -264,34 +264,6 @@ ossl_dsa_get_params(VALUE self)
return hash; return hash;
} }
/*
* call-seq:
* dsa.to_text -> aString
*
* Prints all parameters of key to buffer
* INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
* Don't use :-)) (I's up to you)
*/
static VALUE
ossl_dsa_to_text(VALUE self)
{
DSA *dsa;
BIO *out;
VALUE str;
GetDSA(self, dsa);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
str = ossl_membio2str(out);
return str;
}
/* /*
* call-seq: * call-seq:
* dsa.public_key -> aDSA * dsa.public_key -> aDSA
@ -469,7 +441,6 @@ Init_ossl_dsa(void)
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);
rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0);
rb_define_method(cDSA, "export", ossl_dsa_export, -1); rb_define_method(cDSA, "export", ossl_dsa_export, -1);
rb_define_alias(cDSA, "to_pem", "export"); rb_define_alias(cDSA, "to_pem", "export");
rb_define_alias(cDSA, "to_s", "export"); rb_define_alias(cDSA, "to_s", "export");

View file

@ -412,32 +412,6 @@ ossl_ec_key_to_der(VALUE self)
else else
return ossl_pkey_export_spki(self, 1); return ossl_pkey_export_spki(self, 1);
} }
/*
* call-seq:
* key.to_text => String
*
* See the OpenSSL documentation for EC_KEY_print()
*/
static VALUE ossl_ec_key_to_text(VALUE self)
{
EC_KEY *ec;
BIO *out;
VALUE str;
GetEC(self, ec);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eECError, "BIO_new(BIO_s_mem())");
}
if (!EC_KEY_print(out, ec, 0)) {
BIO_free(out);
ossl_raise(eECError, "EC_KEY_print");
}
str = ossl_membio2str(out);
return str;
}
/* /*
* call-seq: * call-seq:
* key.generate_key! => self * key.generate_key! => self
@ -1601,7 +1575,6 @@ void Init_ossl_ec(void)
rb_define_method(cEC, "export", ossl_ec_key_export, -1); rb_define_method(cEC, "export", ossl_ec_key_export, -1);
rb_define_alias(cEC, "to_pem", "export"); rb_define_alias(cEC, "to_pem", "export");
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0); rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc); rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);

View file

@ -587,36 +587,6 @@ ossl_rsa_get_params(VALUE self)
return hash; return hash;
} }
/*
* call-seq:
* rsa.to_text => String
*
* THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
*
* Dumps all parameters of a keypair to a String
*
* Don't use :-)) (It's up to you)
*/
static VALUE
ossl_rsa_to_text(VALUE self)
{
RSA *rsa;
BIO *out;
VALUE str;
GetRSA(self, rsa);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL);
}
if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
BIO_free(out);
ossl_raise(eRSAError, NULL);
}
str = ossl_membio2str(out);
return str;
}
/* /*
* call-seq: * call-seq:
* rsa.public_key -> RSA * rsa.public_key -> RSA
@ -738,7 +708,6 @@ Init_ossl_rsa(void)
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
rb_define_method(cRSA, "export", ossl_rsa_export, -1); rb_define_method(cRSA, "export", ossl_rsa_export, -1);
rb_define_alias(cRSA, "to_pem", "export"); rb_define_alias(cRSA, "to_pem", "export");
rb_define_alias(cRSA, "to_s", "export"); rb_define_alias(cRSA, "to_s", "export");

View file

@ -169,4 +169,9 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
key1.compare?(key4) key1.compare?(key4)
end end
end end
def test_to_text
rsa = Fixtures.pkey("rsa1024")
assert_include rsa.to_text, "publicExponent"
end
end end