Index: ruby/ext/openssl/ossl_pkey_ec.c
===================================================================
--- ruby/ext/openssl/ossl_pkey_ec.c	(revision 30969)
+++ ruby/ext/openssl/ossl_pkey_ec.c	(working copy)
@@ -152,6 +152,7 @@
  *     OpenSSL::PKey::EC.new(ec_group)
  *     OpenSSL::PKey::EC.new("secp112r1")
  *     OpenSSL::PKey::EC.new(pem_string)
+ *     OpenSSL::PKey::EC.new(pem_string [, pwd])
  *     OpenSSL::PKey::EC.new(der_string)
  *
  *  See the OpenSSL documentation for:
@@ -163,6 +164,7 @@
     EC_KEY *ec = NULL;
     VALUE arg, pass;
     VALUE group = Qnil;
+    char *passwd = NULL;
 
     GetPKey(self, pkey);
     if (pkey->pkey.ec)
@@ -183,11 +185,13 @@
         	group = arg;
         } else {
             BIO *in = ossl_obj2bio(arg);
-
-            ec = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
+            if (!NIL_P(pass)) {
+                passwd = StringValuePtr(pass);
+            }
+            ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
             if (!ec) {
                 (void)BIO_reset(in);
-                ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
+                ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
             }
             if (!ec) {
                 (void)BIO_reset(in);
@@ -457,16 +461,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 +487,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 +529,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 +553,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 +1524,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);
 

