[#35027] [Ruby 1.9-Bug#4352][Open] [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s) — "James M. Lawrence" <redmine@...>

Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)

16 messages 2011/02/01

[#35114] [Ruby 1.9-Bug#4373][Open] http.rb:677: [BUG] Segmentation fault — Christian Fazzini <redmine@...>

Bug #4373: http.rb:677: [BUG] Segmentation fault

59 messages 2011/02/06

[#35171] [Ruby 1.9-Bug#4386][Open] encoding: directive does not affect regex expressions — mathew murphy <redmine@...>

Bug #4386: encoding: directive does not affect regex expressions

9 messages 2011/02/09

[#35237] [Ruby 1.9-Bug#4400][Open] nested at_exit hooks run in strange order — Suraj Kurapati <redmine@...>

Bug #4400: nested at_exit hooks run in strange order

12 messages 2011/02/15

[ruby-core:35329] [Ruby 1.9-Feature#4423][Open] [ext/openssl] Allow encryption for PEM-encoding Elliptic Curve private keys

From: Martin Bosslet <redmine@...>
Date: 2011-02-21 23:36:21 UTC
List: ruby-core #35329
Feature #4423: [ext/openssl] Allow encryption for PEM-encoding Elliptic Curve private keys
http://redmine.ruby-lang.org/issues/show/4423

Author: Martin Bosslet
Status: Open, Priority: Normal
Category: ext, Target version: 1.9.3

There has already been some #if 0-excluded code that would actually
take care of this, but it has not been implemented yet. The attached 
patch allows to encrypt PEM-encoded private keys, Cipher and password
are ignored in the case of public keys (rather than raising an error).

The motivation for this patch is that it would provide uniform behavior 
of all three public key systems supported in Ruby, RSA, DSA (who already
support PEM encryption) and now also Elliptic Curve. RDoc has been 
supplemented.

Regards,
Martin


----------------------------------------
http://redmine.ruby-lang.org

Attachments (1)

ec_pem_pwd.diff (3.37 KB, text/x-diff)
Index: ruby/ext/openssl/ossl_pkey_ec.c
===================================================================
--- ruby/ext/openssl/ossl_pkey_ec.c	(revision 30938)
+++ ruby/ext/openssl/ossl_pkey_ec.c	(working copy)
@@ -457,16 +457,13 @@
     return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);
 }
 
-static VALUE ossl_ec_key_to_string(VALUE self, int format)
+static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
 {
     EC_KEY *ec;
     BIO *out;
     int i = -1;
     int private = 0;
-#if 0  /* unused now */
-    EVP_CIPHER *cipher = NULL;
     char *password = NULL;
-#endif
     VALUE str;
 
     Require_EC_KEY(self, ec);
@@ -486,37 +483,26 @@
     switch(format) {
     case EXPORT_PEM:
     	if (private) {
-#if 0  /* unused now */
-    	    if (cipher || password)
-/* BUG: finish cipher/password key export */
-    	        rb_notimplement();
+	    const EVP_CIPHER *cipher;
+	    if (!NIL_P(ciph)) {
+		cipher = GetCipherPtr(ciph);
+		if (!NIL_P(pass)) {
+		    password = StringValuePtr(pass);
+		}
+	    }
+	    else {
+		cipher = NULL;
+	    }
             i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
-#endif
-            i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
     	} else {
-#if 0  /* unused now */
-    	    if (cipher || password)
-                rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
-#endif
-
             i = PEM_write_bio_EC_PUBKEY(out, ec);
         }
 
     	break;
     case EXPORT_DER:
         if (private) {
-#if 0  /* unused now */
-    	    if (cipher || password)
-                rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
-#endif
-
             i = i2d_ECPrivateKey_bio(out, ec);
         } else {
-#if 0  /* unused now */
-    	    if (cipher || password)
-                rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
-#endif
-
             i = i2d_EC_PUBKEY_bio(out, ec);
         }
 
@@ -539,12 +525,20 @@
 /*
  *  call-seq:
  *     key.to_pem   => String
+ *     key.to_pem(cipher, pass_phrase) => String
  *
- *  See the OpenSSL documentation for PEM_write_bio_ECPrivateKey()
+ * Outputs the EC key in PEM encoding.  If +cipher+ and +pass_phrase+ are
+ * given they will be used to encrypt the key.  +cipher+ must be an
+ * OpenSSL::Cipher::Cipher instance. Note that encryption will only be
+ * effective for a private key, public keys will always be encoded in plain
+ * text.
+ *
  */
-static VALUE ossl_ec_key_to_pem(VALUE self)
+static VALUE ossl_ec_key_to_pem(int argc, VALUE *argv, VALUE self)
 {
-    return ossl_ec_key_to_string(self, EXPORT_PEM);
+    VALUE cipher, passwd;
+    rb_scan_args(argc, argv, "02", &cipher, &passwd);
+    return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
 }
 
 /*
@@ -555,7 +549,7 @@
  */
 static VALUE ossl_ec_key_to_der(VALUE self)
 {
-    return ossl_ec_key_to_string(self, EXPORT_DER);
+    return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
 }
 
 /*
@@ -1526,7 +1520,7 @@
     rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
 /* do_sign/do_verify */
 
-    rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, 0);
+    rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, -1);
     rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
     rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
 

In This Thread

Prev Next