summaryrefslogtreecommitdiff
path: root/ext/openssl
diff options
context:
space:
mode:
authoremboss <emboss@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-06-12 20:39:38 +0000
committeremboss <emboss@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-06-12 20:39:38 +0000
commitbbb3cfb12b16c7681a58e9a16cec49c37edab1ab (patch)
tree27d8a24a2f44b9e153f577cb68fb0faa54aa1fac /ext/openssl
parent7b614a53dd50508410c48113dce87abfc003df6b (diff)
* ext/openssl/ossl_pkey.c: added PKey.read module function that allow
reading arbitrary public/private keys from DER-/PEM-encoded File or string instances. * ext/openssl/ossl_pkey_dh.c: improved documentation. * test/openssl/utils.rb: added EC test key. * test/openssl/test_pkey_rsa.rb test/openssl/test_pkey_dsa.rb: Test PKey.read. Reuse keys from OpenSSL::TestUtils. * test/openssl/test_pkey_ec.rb: Created test file for EC tests. Test PKey.read. [Ruby 1.9 - Feature #4424] [ruby-core:35330] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32036 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl')
-rw-r--r--ext/openssl/ossl_pkey.c53
-rw-r--r--ext/openssl/ossl_pkey_dh.c19
2 files changed, 66 insertions, 6 deletions
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 69747ca44a..0bd9dda549 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -18,6 +18,9 @@ VALUE cPKey;
VALUE ePKeyError;
ID id_private_q;
+#define reset_bio(b) (void)BIO_reset((b)); \
+ (void)ERR_get_error();
+
/*
* callback for generating keys
*/
@@ -85,6 +88,54 @@ ossl_pkey_new_from_file(VALUE filename)
return ossl_pkey_new(pkey);
}
+/*
+ * call-seq:
+ * OpenSSL::PKey.read(string [, pwd ] ) -> PKey
+ * OpenSSL::PKey.read(file [, pwd ]) -> PKey
+ *
+ * === Parameters
+ * * +string+ is a DER- or PEM-encoded string containing an arbitrary private
+ * or public key.
+ * * +file+ is an instance of +File+ containing a DER- or PEM-encoded
+ * arbitrary private or public key.
+ * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
+ * PEM resource.
+ */
+static VALUE
+ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
+{
+ FILE *fp;
+ EVP_PKEY *pkey;
+ BIO *bio;
+ VALUE data, pass;
+ char *passwd = NULL;
+
+ rb_scan_args(argc, argv, "11", &data, &pass);
+
+ bio = ossl_obj2bio(data);
+ if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
+ reset_bio(bio);
+ if (!NIL_P(pass)) {
+ passwd = StringValuePtr(pass);
+ }
+ if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
+ reset_bio(bio);
+ if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
+ reset_bio(bio);
+ if (!NIL_P(pass)) {
+ passwd = StringValuePtr(pass);
+ }
+ pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
+ }
+ }
+ }
+
+ BIO_free(bio);
+ if (!pkey)
+ ossl_raise(rb_eArgError, "Could not parse PKey");
+ return ossl_pkey_new(pkey);
+}
+
EVP_PKEY *
GetPKeyPtr(VALUE obj)
{
@@ -330,6 +381,8 @@ Init_ossl_pkey()
*/
cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
+ rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
+
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 3f1ebda8d0..834261087a 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -338,15 +338,17 @@ ossl_dh_to_text(VALUE self)
* call-seq:
* dh.public_key -> aDH
*
- * Returns a new DH instance that carries just the public information.
- * If the current instance has also private information, this will no
+ * Returns a new DH instance that carries just the public information, i.e.
+ * the prime +p+ and the generator +g+, but no public/private key yet. Such
+ * a pair may be generated using DH#generate_key!.
+ * If the current instance already contains private information, this will no
* longer be present in the new instance. This feature is helpful for
* publishing the public information without leaking any of the private
* information.
*
* === Example
* dh = OpenSSL::PKey::DH.new(2048) # has public and private information
- * pub_key = dh.public_key # has only the public part available
+ * pub_key = dh.public_key # contains only prime and generator
* pub_key_der = pub_key.to_der # it's safe to publish this
*/
static VALUE
@@ -394,10 +396,15 @@ ossl_dh_check_params(VALUE self)
/*
* call-seq:
- * dh.generate_key -> self
+ * dh.generate_key! -> self
*
- * Generates a private key unless one already exists. It also computes the
- * public key for the generated private key.
+ * Generates a private and public key unless one already exists.
+ *
+ * === Example
+ * dh = OpenSSL::PKey::DH.new(2048)
+ * public_key = dh.public_key #contains no private/public key yet
+ * public_key.generate_key!
+ * puts public_key.private? # => true
*/
static VALUE
ossl_dh_generate_key(VALUE self)